"""
Case Type   : dsscmd交互式
Case Name   : 交互式模式下，
Create At   : 2024/10
Owner       : haomeng
Description :
    1、进入交互模式，查看共享内存信息
    2、进入交互模式，查看共享内存信息，指定block_id
    3、进入交互模式，查看共享内存信息，指定-g/-f/-n/-o/-z
    4、进入交互模式，查看共享内存信息，指定-p/-o/-z
    5、进入交互模式，从黑匣子中生成的共享内存文件获取共享内存信息
Expect      :
    1、查看成功
    2、查看成功
    3、查看成功
    4、查看成功
    5、查看成功
History     :
"""


import os
import time
import unittest

from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from yat.test import Node
from yat.test import macro


class DsscmdInteractive(unittest.TestCase):

    def setUp(self):
        self.log = Logger()
        self.log.info(f'----{os.path.basename(__file__)} start----')
        self.node = Node('PrimaryDbUser')
        self.com = Common()
        self.blockid_path = os.path.join(macro.DSS_INSTANCE_PATH, 'log/debug/dsscmd.dlog')
        self.black_path = os.path.join(macro.DSS_INSTANCE_PATH, 'log/blackbox/')

    def test_dsscmd(self):
        text = '-----step1:进入交互式模式，查看共享内存信息   expect:查看成功-----'
        self.log.info(text)
        time.sleep(10)

        cmd = '''dsscmd --interactive'''
        param_list1 = ['core_ctrl', 'vg_header', 'volume_ctrl', 'root_ft_block']
        for param in param_list1:
            execute_cmd1 = f'''source {macro.DB_ENV_PATH};
                         expect <<EOF
                         set timeout 3
                         spawn {cmd}
                         expect "dsscmd>"
                         send "showmem -g data -s {param}\\n"
                         expect "dsscmd>"
                         send "exit\\n"
                         expect eof\n''' + '''EOF'''
            self.log.info(execute_cmd1)
            res1 = self.node.sh(execute_cmd1).result()
            self.log.info(res1)
            self.assertIn('Succeed to printf dss metadata', res1, '查看共享内存信息失败')

        for param in param_list1:
            execute_cmd2 = f'''source {macro.DB_ENV_PATH};
                         expect <<EOF
                         set timeout 3
                         spawn {cmd}
                         expect "dsscmd>"
                         send "showmem -g log -s {param}\\n"
                         expect "dsscmd>"
                         send "exit\\n"
                         expect eof\n''' + '''EOF'''
            self.log.info(execute_cmd2)
            res2 = self.node.sh(execute_cmd2).result()
            self.log.info(res2)
            self.assertIn('Succeed to printf dss metadata', res2, '查看共享内存信息失败')

        text = '-----step2:进入交互式模式，查看共享内存信息，指定block_id   expect:查看成功-----'
        self.log.info(text)

        blockid_info = f'cat {self.blockid_path} | grep blockid | tail -n 1'
        self.log.info(blockid_info)
        blockid_res = self.node.sh(blockid_info).result()
        self.log.info(blockid_res)
        block_id = blockid_res.split('metaid:')[-1].split('(')[0].strip()

        execute_cmd3 = f'''source {macro.DB_ENV_PATH};
                     expect <<EOF
                     set timeout 3
                     spawn {cmd}
                     expect "dsscmd>"
                     send "showmem -g data -b {block_id} -n 0\\n"
                     expect "dsscmd>"
                     send "exit\\n"
                     expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd3)
        res3 = self.node.sh(execute_cmd3).result()
        self.log.info(res3)
        self.assertIn(f'block_id', res3, '查看共享内存信息失败')

        text = '-----step3:进入交互式模式，查看共享内存信息，指定-g/-f/-n/-o/-z   expect:查看成功-----'
        self.log.info(text)

        execute_cmd4 = f'''source {macro.DB_ENV_PATH};
                     expect <<EOF
                     set timeout 3
                     spawn {cmd}
                     expect "dsscmd>"
                     send "showmem -g data -f 6 -n 0 -o 512 -z 3126\\n"
                     expect "dsscmd>"
                     send "exit\\n"
                     expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd4)
        res4 = self.node.sh(execute_cmd4).result()
        self.log.info(res4)
        self.assertIn(f'type', res4, '查看共享内存信息失败')

        text = '-----step4:进入交互式模式，查看共享内存信息，指定-p/-o/-z   expect:查看成功-----'
        self.log.info(text)

        execute_cmd5 = f'''source {macro.DB_ENV_PATH};
                     expect <<EOF
                     set timeout 3
                     spawn {cmd}
                     expect "dsscmd>"
                     send "showmem -p +data/pg_control.backup -o 512 -z 3126\\n"
                     expect "dsscmd>"
                     send "exit\\n"
                     expect eof\n''' + '''EOF'''
        self.log.info(execute_cmd5)
        res5 = self.node.sh(execute_cmd5).result()
        self.log.info(res5)
        self.assertIn(f'type', res5, '查看共享内存信息失败')

        text = '-----step5:进入交互式模式，从黑匣子中生成的共享内存文件获取共享内存信息  expect:查看成功-----'
        self.log.info(text)

        self.log.info('-----开启黑匣子日志-----')
        black_res = self.node.sh(f'source {macro.DB_ENV_PATH};'
                                f'gs_ssh -c "dsscmd setcfg -n _BLACKBOX_DETAIL_ON -v TRUE"').result()
        self.log.info(black_res)
        self.assertIn('Successfully execute command on all nodes', black_res, '开启黑匣子失败')

        self.log.info('-----kill掉dss进程使其产生黑侠在日志-----')
        dss_pid = self.com.get_pid(self.node, 'dssserver')
        self.log.info(dss_pid)
        kill_dss = self.node.sh(f'''kill -9 {dss_pid}''').result()
        self.log.info(kill_dss)
        self.assertEqual('', kill_dss, 'kill掉dss进程失败')

        black_cmd = f'ls {self.black_path}'
        black_res = self.node.sh(black_cmd).result()
        self.log.info(black_res)

        black_file = black_res.split()[-1]

        for param in param_list1:
            execute_cmd6 = f'''source {macro.DB_ENV_PATH};
                         expect <<EOF
                         set timeout 3
                         spawn {cmd}
                         expect "dsscmd>"
                         send "fshowmem -m {self.black_path}/{black_file} -g data -s {param}\\n"
                         expect "dsscmd>"
                         send "exit\\n"
                         expect eof\n''' + '''EOF'''
            self.log.info(execute_cmd6)
            res6 = self.node.sh(execute_cmd6).result()
            self.log.info(res6)
            self.assertIn('Succeed to printf dss metadata', res6, '查看黑匣子共享内存信息失败')

        for param in param_list1:
            execute_cmd7 = f'''source {macro.DB_ENV_PATH};
                         expect <<EOF
                         set timeout 3
                         spawn {cmd}
                         expect "dsscmd>"
                         send "fshowmem -m {self.black_path}/{black_file} -g log -s {param}\\n"
                         expect "dsscmd>"
                         send "exit\\n"
                         expect eof\n''' + '''EOF'''
            self.log.info(execute_cmd7)
            res7 = self.node.sh(execute_cmd7).result()
            self.log.info(res7)
            self.assertIn('Succeed to printf dss metadata', res7, '查看黑匣子共享内存信息失败')

    def tearDown(self):
        text = '-----No need to clean-----'
        self.log.info(text)
        self.log.info(f'----{os.path.basename(__file__)} end----')
